/**
  * <br>JAVACC DEMO 1.0<br>
  * <br>
  * @Package com.apache.dict.impl
*/
package com.apache.dict.service.impl;

import java.util.List;

import com.apache.api.vo.ParamsVo;
import com.apache.cache.util.Validator;
import com.apache.database.model.MethodParam;
import com.apache.database.model.Page;
import com.apache.dict.entity.DataItem;
import com.apache.dict.manager.CacheTacticsPlugin;
import com.apache.dict.manager.DataItemManager;
import com.apache.dict.service.AbstractBaseManager;
import com.apache.dict.vo.ItemListVo;
import com.apache.exception.BusinessException;

/**
  * description: 数据字典条目业务逻辑接口实现
  * @author Hou DaYu 创建时间：上午09:39:54
  */
public class DataItemManagerImpl extends AbstractBaseManager implements DataItemManager {

	protected final String entityName = "com.apache.dict.entity.DataItem";

	protected CacheTacticsPlugin cacheTactics;

	/* (non-Javadoc)
	 * @see com.apache.api.manager.BaseManager#saveInfo(com.apache.api.vo.ParamsVo)
	 */
	public String saveInfo(ParamsVo<DataItem> vo) throws BusinessException {
		DataItem dataItem = vo.getObj();
		String itemId = Validator.generate();
		dataItem.setItemId(itemId);
		dataItem.setCreateTime(System.currentTimeMillis());
		dataItem.setSubCount(0);//根条目默认为0
		String fatherId = Validator.getDefaultStr(dataItem.getFatherId(), "0");//获取父节点ID，如果没有父节点，则默认0
		dataItem.setFatherId(fatherId);
		String fullCname = "";
		String fullEname = "";
		/**之所以用itemid拼装fullename是因为itemvalue是可变的*/
		if ("0".equals(fatherId)) {//添加根条目
			fullCname = "/" + dataItem.getItemText();
			fullEname = "/" + dataItem.getItemId();
			dataItem.setFatherId("0");
			dataItem.setFatherValue("0");
		} else {//添加子条目
			MethodParam param = new MethodParam("ById", "item_" + fatherId, "", entityName);
			param.setInfoId(fatherId);
			DataItem father = (DataItem) dataItemDao.selectById(param);//获取父节点对象
			if (null != father) {
				fullCname = father.getFullCname() + "/" + dataItem.getItemText();
				fullEname = father.getFullEname() + "/" + dataItem.getItemId();
				fullCname.replaceAll("//", "/");
				fullEname.replaceAll("//", "/");
				dataItem.setFatherValue(father.getItemValue());
				dataItem.setFatherId(father.getItemId());
				updateSubCount(father, 1);
			}
		}
		MethodParam param = new MethodParam("DataItem", "item_" + itemId, "", entityName);
		dataItem.setFullEname(fullEname);
		dataItem.setFullCname(fullCname);
		param.setVaule(dataItem);
		if (dataItemDao.insert(param)) {
			cacheTactics.createItem(dataItem.getCateEname(), itemId);
			return itemId;
		}
		return "";
	}

	/**
	 * 添加子条目时，更新对应的根条目的子节点个数
	 * @param father 根条目对象
	 * @param num
	 */
	private void updateSubCount(DataItem father, int num) {
		/** 父节点的子节点总数 */
		if (father != null) {
			//获取当前父节点的子节点个数
			int subCount = father.getSubCount() == null ? 0 : father.getSubCount().intValue();
			subCount += num;
			if (subCount < 0) {
				subCount = 0;
			}
			father.setSubCount(Integer.valueOf(subCount));
			MethodParam param = new MethodParam("DataItem", "item_" + father.getItemId(), "", entityName);
			param.setVaule(father);
			dataItemDao.edit(param);
		}
	}

	/* (non-Javadoc)
	 * @see com.apache.api.manager.BaseManager#deleteInfo(com.apache.api.vo.ParamsVo)
	 */
	public boolean deleteInfo(ParamsVo<DataItem> vo) throws BusinessException {
		String itemId = vo.getInfoId();
		if (Validator.isNull(itemId))
			return false;

		MethodParam param = new MethodParam("ById", "item_" + itemId, "", entityName);
		param.setInfoId(itemId);
		DataItem dataItem = (DataItem) dataCateDao.selectById(param);
		if (Validator.isEmpty(param)) {
			return false;
		}
		param.setVaule(dataItem);
		param.setDelete(true);
		param.setParams("itemId", vo.getInfoId());
		boolean mark = dataItemDao.delete(param);
		String fatherId = Validator.getDefaultStr(dataItem.getFatherId(), "0");
		if (!"0".equals(fatherId)) {//更新子节点数
			MethodParam mp = new MethodParam("ById", "item_" + dataItem.getFatherId(), "", entityName);
			mp.setInfoId(fatherId);
			DataItem father = (DataItem) dataItemDao.selectById(mp);//获取父节点对象
			if (null != father) {
				mp = new MethodParam("ByCateEnameAndItemValue", "item_" + father.getItemId(), dataItemDao.getSql(5),
						entityName);
				mp.setParams("fatherId", father.getItemId());
				Long count = dataItemDao.count(mp);
				//更新父节点子节点数
				father.setSubCount(count.intValue());
				mp.setVaule(father);
				mp.setKey("DataItem");
				mp.setSqlStr("");
				dataItemDao.edit(mp);
			}
		}
		if (mark) {
			cacheTactics.removeItem(dataItem.getCateEname(), itemId);
		}
		return mark;
	}

	/* (non-Javadoc)
	 * @see com.apache.api.manager.BaseManager#editInfo(com.apache.api.vo.ParamsVo)
	 */
	public boolean editInfo(ParamsVo<DataItem> vo) throws BusinessException {
		DataItem dataItem = vo.getObj();
		String itemId = dataItem.getItemId();
		if (Validator.isNotNull(itemId)) {
			String fatherId = dataItem.getFatherId();
			fatherId = Validator.getDefaultStr(fatherId, "0");//获取父节点ID，如果没有父节点，则默认0
			String fullCname = "";
			String fullEname = "";
			/**之所以用itemid拼装fullename是因为itemvalue是可变的*/
			if ("0".equals(fatherId)) {//添加根条目
				fullCname = "/" + dataItem.getItemText();
				fullEname = "/" + dataItem.getItemId();
				dataItem.setFatherId("0");
				dataItem.setFatherValue("0");
			} else {//添加子条目
				MethodParam param = new MethodParam("ById", "item_" + fatherId, "", entityName);
				param.setInfoId(fatherId);
				DataItem father = (DataItem) dataItemDao.selectById(param);//获取父节点对象
				if (null != father) {
					fullCname = father.getFullCname() + "/" + dataItem.getItemText();
					fullEname = father.getFullEname() + "/" + dataItem.getItemId();
					fullCname.replaceAll("//", "/");
					fullEname.replaceAll("//", "/");
					dataItem.setFatherValue(father.getItemValue());
					dataItem.setFatherId(father.getItemId());
				}
			}
			dataItem.setFullEname(fullEname);
			dataItem.setFullCname(fullCname);
			dataItem.setUpdateTime(System.currentTimeMillis());
			MethodParam param = new MethodParam("ByCateEnameAndItemValue", "item_" + itemId,
					"select count(*) from DataItem t where t.fatherId =:fatherId", entityName);
			param.setParams("fatherId", itemId);
			Long count = dataItemDao.count(param);
			dataItem.setSubCount(count.intValue());
			param.setVaule(dataItem);
			param.setKey("DataItem");
			param.setSqlStr("");
			return dataItemDao.edit(param);
		}
		return false;
	}

	/* (non-Javadoc)
	 * @see com.apache.api.manager.BaseManager#execute(com.apache.api.vo.ParamsVo)
	 */
	public Object execute(ParamsVo<DataItem> vo) {
		String methodKey = vo.getMethodKey();
		if ("checkDataItemByFatherId".equalsIgnoreCase(methodKey)) {//是否有子列表
			String cateEname = String.valueOf(vo.getParams("cateEname"));
			String fatherId = String.valueOf(vo.getParams("fatherId"));
			return checkDataItemByFatherId(cateEname, fatherId);
		} else if ("checkCateEnameAndItemValue".equalsIgnoreCase(methodKey)) {
			String cateEname = String.valueOf(vo.getParams("cateEname"));
			String itemValue = String.valueOf(vo.getParams("itemValue"));
			return checkCateEnameAndItemValue(cateEname, itemValue);
		} else if ("ByCateEnameAndItemValue".equalsIgnoreCase(methodKey)) {
			String cateEname = String.valueOf(vo.getParams("cateEname"));
			String itemValue = String.valueOf(vo.getParams("itemValue"));
			return selectCateEnameAndItemValue(cateEname, itemValue);
		} else if ("ByService".equals(methodKey)) {
			String cateEname = String.valueOf(vo.getParams("cateEname"));
			String fatherValue = String.valueOf(vo.getParams("fatherValue"));
			String page = String.valueOf(vo.getParams("pageIndex"));
			String pageSize = String.valueOf(vo.getParams("pageSize"));
			return getItems(cateEname, fatherValue, page, pageSize);
		}
		return null;
	}

	private Object getItems(String cateEname, String fatherValue, String page, String pageSize) {
		MethodParam param = new MethodParam("ByService", "", "", entityName);
		param.setParams("cateEname", cateEname);
		param.setParams("fatherValue", fatherValue);
		if (Validator.isNotNull(pageSize)) {
			param.setPageSize(Integer.valueOf(pageSize));
			param.setPageIndex(Integer.valueOf(Validator.getDefaultStr(page, "1")));
		}
		return dataItemDao.select(param);
	}

	/**
	 * 查检是否有子列表
	 * @param cateEname 科目标识
	 * @param fatherId  父节点ID
	 * @return 有子列表返回true,反之返回false;
	 */
	private boolean checkDataItemByFatherId(String cateEname, String fatherId) {
		boolean mark = false;
		String sql = dataItemDao.getSql(3);
		MethodParam param = new MethodParam("ByCateEnameAndItemValue", "", sql, entityName);
		param.setParams("cateEname", cateEname);
		param.setParams("fatherId", fatherId);
		long count = dataItemDao.count(param);
		if (count > 0)
			return true;
		return mark;
	}

	/**
	 * 查检判断新添加的条目是否存在
	 * @param cateEname 科目标识
	 * @param itemValue 条目标识
	 * @return 存在返回true,反之返回false;
	 */
	private boolean checkCateEnameAndItemValue(String cateEname, String itemValue) {
		boolean mark = false;
		String sql = dataItemDao.getSql(4);
		MethodParam param = new MethodParam("ByCateEnameAndItemValue", "", sql, entityName);
		param.setParams("cateEname", cateEname);
		param.setParams("itemValue", itemValue);
		long count = dataItemDao.count(param);
		if (count > 0)
			return true;
		return mark;
	}

	private DataItem selectCateEnameAndItemValue(String cateEname, String itemValue) {
		String sql = dataItemDao.getSql(4);
		MethodParam param = new MethodParam("ByCateEnameAndItemValue", "", sql, entityName);
		param.setParams("cateEname", cateEname);
		param.setParams("itemValue", itemValue);
		Object obj = dataItemDao.selectSingle(param);
		return (DataItem) obj;
	}

	/* (non-Javadoc)
	 * @see com.apache.api.manager.BaseManager#getInfoById(com.apache.api.vo.ParamsVo)
	 */
	public Object getInfoById(ParamsVo<DataItem> vo) {
		String itemId = vo.getInfoId();
		if (Validator.isNull(itemId))
			return null;
		MethodParam param = new MethodParam("ById", "item_" + itemId, "", entityName);
		param.setInfoId(itemId);
		return dataItemDao.selectById(param);
	}

	/* (non-Javadoc)
	 * @see com.apache.api.manager.BaseManager#getList(com.apache.api.vo.ParamsVo)
	 */
	@SuppressWarnings("unchecked")
	public List<DataItem> getList(ParamsVo vo) {
		List<DataItem> result = cacheTactics.getDataItems((ItemListVo) vo.getObj());
		if (!Validator.isEmpty(result)) {
			return result;
		}
		MethodParam param = setMethodParams(vo, 1);
		param.setSqlStr(param.getSqlStr() + " order by itemValue ASC");
		param.setParams("orderList", " order by item_Value asc");
		return dataItemDao.select(param);
	}

	public Page getPageInfo(ParamsVo<ItemListVo> vo) {
		MethodParam param = setMethodParams(vo, 1);
		param.setSqlStr(param.getSqlStr() + " order by itemValue asc");
		param.setParams("orderList", " order by item_Value asc");
		int pageSize = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageSize")), "10"));
		int pageIndex = Integer.valueOf(Validator.getDefaultStr(String.valueOf(vo.getParams("pageIndex")), "1"));
		param.setPageIndex(pageIndex);
		param.setPageSize(pageSize);
		Page page = dataItemDao.pageSelect(param);
		return page;
	}

	/* (non-Javadoc)
	 * @see com.apache.api.manager.BaseManager#countInfo(com.apache.api.vo.ParamsVo)
	 */
	public long countInfo(ParamsVo vo) {
		MethodParam param = setMethodParams(vo, 2);
		return dataItemDao.count(param);
	}

	public void initSystemCache() {
		cacheTactics.initItem();
	}

	private MethodParam setMethodParams(ParamsVo vo, int type) {
		ItemListVo item = (ItemListVo) vo.getObj();
		StringBuffer sb = new StringBuffer(dataItemDao.getSql(type));
		String methodKey = Validator.getDefaultStr(vo.getMethodKey(), "ByProperty");
		MethodParam param = new MethodParam(methodKey, "", "", entityName);
		if (null == item) {
			param.setSqlStr(sb.toString());
			return param;
		}
		if (Validator.isNotNull(item.getCateEname())) {
			sb.append(" and cateEname = :cateEname");
			param.setParams("cateEname", item.getCateEname());
		}

		if (Validator.isNotNull(item.getItemText())) {
			sb.append(" and itemText like :itemText");
			param.setParams("itemText", "'%" + item.getItemText() + "%' ");
		}

		if (Validator.isNotNull(item.getItemValue())) {
			sb.append(" and itemValue like :itemValue");
			param.setParams("itemValue", "'%" + item.getItemValue() + "%' ");
		}

		if (Validator.isNotNull(item.getFatherId())) {
			sb.append(" and fatherId = :fatherId");
			param.setParams("fatherId", item.getFatherId());
		}

		if (Validator.isNotNull(item.getFatherValue())) {
			sb.append(" and fatherValue = :fatherValue");
			param.setParams("fatherValue", item.getFatherValue());
		}
		if (Validator.isNotNull(item.getItemStatus())) {
			sb.append(" and itemStatus = :itemStatus");
			param.setParams("itemStatus", item.getItemStatus());
		}
		param.setSqlStr(sb.toString());
		return param;
	}

	public void setCacheTactics(CacheTacticsPlugin cacheTactics) {
		this.cacheTactics = cacheTactics;
	}

}
